#include <iostream>
#include <typeinfo>
#include <cassert>
#include <unistd.h>

class Any
{
public:
    // 构造空对象
    Any()
    {
        _content = nullptr;
    }

    // 传值构造一个Any对象
    template <class T>
    Any(T &val)
    {
        _content =new placeholder<T>(val);
    }

    // 拷贝构造
    Any(Any &other)
    {
        if(other._content == nullptr)
        {
            this->_content = nullptr;
            return;
        }

        this->_content = other._content->Clone();
    }

    // 析构释放指针
    ~Any()
    {
        if(_content == nullptr)
        {
            return;
        }
        delete _content;
    }

    // 交换两个Any对象(指针交换)
    Any &Swap(Any &other)
    {
        std::swap(_content, other._content);
        return *this;
    }

    // 赋值运算符重载
    // 1.对象赋值 2.具体数据赋值
    Any operator=(const Any &other)
    {
        Any(other).Swap(*this);

        return *this;
    }

    template <class T>
    Any operator=(const T &val)
    {
        Any tmp(val);
        tmp.Swap(*this);

        return *this;
    }

    // 返回保存数据的指针(具体类型的指针)
    template <class T>
    T* Getptr()
    {
        assert(typeid(T) == _content->Info());
        return &((placeholder<T>*)_content)->_val;
    }

private:
    class holder
    {
    public:
        virtual ~holder() {}
        virtual const std::type_info &Info() = 0;
        virtual holder *Clone() = 0;

    private:
    };
    template <class T>
    class placeholder : public holder
    {
    public:
        placeholder(const T& val)
        :_val(val)
        {}

        const std::type_info &Info() override
        {
            return typeid(T);
        }

        holder *Clone() override
        {
            return new placeholder(_val);
        }

    public:
        T _val;
    };

    holder *_content;
};
class Test{
    public:
        Test() {std::cout << "构造" << std::endl;}
        Test(const Test &t) {std::cout << "拷贝" << std::endl;}
        ~Test() {std::cout << "析构" << std::endl;}
};

int main()
{

    
    Any a;
    {
        Test t;
        a = t;
    }
    
    a = 10;
    int *pa = a.Getptr<int>();
    std::cout << *pa << std::endl;
    a = std::string("nihao");
    std::string *ps = a.Getptr<std::string>();
    std::cout << *ps << std::endl;
    
    
    return 0;
}